package com.google.code.mochaccino.framework.ui.i18n;
/*
 * Copyright 2012 Claude Houle claude.houle@gmail.com
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.util.Enumeration;
import java.util.Locale;
import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;

public abstract class ResourceBundleUTF8 {

	protected static ResourceBundle createBundle( ResourceBundle bundle ) {
		if ( !(bundle instanceof PropertyResourceBundle) ) {
			return bundle;
		}
		return new ResourceBundleUtf8Implementation( (PropertyResourceBundle) bundle );
	}

	public static final ResourceBundle getBundle( String baseName ) {
		return createBundle( ResourceBundle.getBundle( baseName ) );
	}

	public static final ResourceBundle getBundle( String baseName, Locale locale ) {
		return createBundle( ResourceBundle.getBundle( baseName, locale ) );
	}

	public static ResourceBundle getBundle( String baseName, Locale locale, ClassLoader loader ) {
		return createBundle( ResourceBundle.getBundle( baseName, locale, loader ) );
	}

	static class ResourceBundleUtf8Implementation extends ResourceBundle {

		private PropertyResourceBundle bundle;

		protected ResourceBundleUtf8Implementation( PropertyResourceBundle bundle ) {
			this.bundle = bundle;
			this.parent = getParent();
		}

		private ResourceBundle getParent() {
			try {
				// Access the 'parent' field of the Resource Bundle
				Field field = ResourceBundle.class.getDeclaredField( "parent" );
				field.setAccessible( true );
				ResourceBundle parentBundle = (ResourceBundle) field.get( bundle );
				if ( parentBundle == null ) {
					return null;
				}
				return createBundle( parentBundle );
			} catch ( SecurityException e ) {
				throw new RuntimeException( e.getMessage(), e );
			} catch ( NoSuchFieldException e ) {
				throw new RuntimeException( e.getMessage(), e );
			} catch ( IllegalArgumentException e ) {
				throw new RuntimeException( e.getMessage(), e );
			} catch ( IllegalAccessException e ) {
				throw new RuntimeException( e.getMessage(), e );
			}
		}

		@Override
		protected Object handleGetObject( String key ) {
			String value = (String) bundle.handleGetObject( key );
			try {
				return new String( value.getBytes( "ISO-8859-1" ), "UTF-8" );
			} catch ( UnsupportedEncodingException e ) {
				return null;
			} catch ( NullPointerException e ) {
				return null;
			}
		}

		@Override
		public Enumeration<String> getKeys() {
			return bundle.getKeys();
		}
	}
}